﻿
using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

namespace DotNetNuke.Modules.UserDefinedTable
{


  public class XSLTemplatingUtilities
  {





    public enum ContextValues
    {
      ApplicationPath,
      CurrentCulture,
      DisplayName,
      HomePath,
      IsAdministratorRole,
      ModuleId,
      OrderBy,
      OrderDirection,
      Parameter,
      PortalId,
      TabId,
      UserName,
      UserRoles,
      LocalizedSearchString,
      NowInTicks,
      TicksPerDay,
      LocalizedDate,
      Now
    }


    public const string HardSpace = "&#160;";
    public const string SpacePlaceholder = "{5A255853-D9A0-4f46-9E9D-F661DC4874CD}";




    public static string GenerateDetailViewTokenText(DataTable Fieldstable)
    {
      return GenerateDetailViewTokenText(Fieldstable, true);
    }




    public static string GenerateDetailViewTokenText(DataTable fieldstable, bool includeEditLink)
    {
      using (StringWriter writer = new StringWriter())
      {
        XmlTextWriter writer3 = new XmlTextWriter(writer);
        writer3.Formatting = Formatting.Indented;
        using (XmlTextWriter writer2 = writer3)
        {
          writer2.WriteStartElement("table");

          foreach(DataRow current in fieldstable.Rows)
          {
            writer2.WriteStartElement("tr");
            writer2.WriteStartElement("td");
            writer2.WriteAttributeString("class", "normalBold");
            writer2.WriteString((string)current[FieldsTableColumn.Title]);
            writer2.WriteEndElement();
            writer2.WriteStartElement("td");
            writer2.WriteAttributeString("class", "Normal");
            writer2.WriteString(string.Format("[{0}]", XmlConvert.DecodeName((string)current[FieldsTableColumn.ValueColumn])));
            writer2.WriteEndElement();
            writer2.WriteEndElement();
          }
          writer2.WriteEndElement();
          writer2.Flush();
          writer2.Close();
        }
        if (includeEditLink)
          return string.Format("[UDT:ListView][UDT:EditLink]{0}{1}", "\r\n", writer);
        
        return writer.ToString();
      }
    }





    private static string LoadXslScriptOption(XmlDocument def, string xsl, string extension, bool IsEnabled)
    {
      string oldValue;

      foreach(XmlElement current in def.SelectNodes(string.Format("root/data[@name=\"{0}\"]", extension)))
      {
        oldValue = string.Format("{{{0}{1}}}", extension.ToUpperInvariant(), current.Attributes["number"].InnerText);
        if (IsEnabled)
          xsl = xsl.Replace(oldValue, HttpUtility.HtmlDecode(current.FirstChild.InnerText));

        else
          xsl = xsl.Replace(oldValue, "");
      }
      return xsl;
    }




    private static string LoadXslScriptTemplate(string ListView, string DetailView, string HeaderView, bool PagingEnabled, bool SortingEnabled, bool SearchEnabled, bool ShowDetailView, string currentListType)
    {
      string str2;
      XmlDocument def = new XmlDocument();
      def.Load(System.Web.HttpContext.Current.Request.MapPath("~/DesktopModules/UserDefinedTable/xslStyleSheets/xslScripts.xml"));
      string xsl = HttpUtility.HtmlDecode(def.SelectSingleNode("/root/data[@name=\"XSLT\"]/value").InnerText);
      xsl = LoadXslScriptOption(def, xsl, "paging", PagingEnabled);
      xsl = LoadXslScriptOption(def, xsl, "sorting", SortingEnabled);
      xsl = LoadXslScriptOption(def, xsl, "searching", SearchEnabled);
      xsl = LoadXslScriptOption(def, xsl, "detail", ShowDetailView).Replace("[LISTVIEW]", ListView).Replace("[DETAILVIEW]", DetailView).Replace("[HEADERVIEW]", HeaderView);

      if (((((currentListType == "table") || (currentListType == "ol")) ? true : false) || (currentListType == "ul")) != false)
        str2 = currentListType;

      else
        str2 = "";

      if (str2 == "")
        return xsl.Replace("[OPENTAG]", "").Replace("[/OPENTAG]", "");

      return xsl.Replace("[OPENTAG]", string.Format("<{0}>", str2)).Replace("[/OPENTAG]", string.Format("</{0}>", str2));
    }





    public static string PrettyPrint(string template)
    {
      XmlDocument doc = new XmlDocument();
      doc.LoadXml(template);
      return PrettyPrint(doc);
    }





    public static string PrettyPrint(XmlDocument doc)
    {
      string str;

      using (StringWriter writer = new StringWriter())
      {
        XmlTextWriter w = new XmlTextWriter(writer);
        try
        {
          w.Formatting = Formatting.Indented;
          doc.WriteTo(w);
          w.Flush();
          w.Close();
          return writer.ToString().Replace("  <xsl:template", string.Format("{0}  <xsl:template", "\r\n"));
        }
        catch (Exception e)
        {
          Exception exception = e;
          str = string.Empty;
          return str;
        }
        finally
        {
          if (w != null)
            ((IDisposable)w).Dispose();
          
        }
      }
      return str;
    }





    public static string TransformTokenTextToXslScript(DataSet udt_dataset, string tokentemplate)
    {
      return TransformTokenTextToXslScript(udt_dataset, tokentemplate, string.Empty, string.Empty, false, false, false, false, string.Empty);
    }





    public static string TransformTokenTextToXslScript(DataSet udt_dataset, string listView, string detailView, string headerView, bool PagingEnabled, bool SortingEnabled, bool SearchEnabled, bool ShowDetailView, string CurrentListType)
    {
      if (SortingEnabled)
        headerView = Regex.Replace(headerView, @"\[((?:\w|\s)+)\]", "<xsl:apply-templates select =\"udt:Fields[udt:FieldTitle='$1']\"/>");

      else
        headerView = Regex.Replace(headerView, @"\[((?:\w|\s)+)\]", "$1");

      string input = LoadXslScriptTemplate(listView, detailView, headerView, PagingEnabled, SortingEnabled, SearchEnabled, ShowDetailView, CurrentListType).Replace("[ ]", "{5A255853-D9A0-4f46-9E9D-F661DC4874CD}").Replace("&#160;", "{5A255853-D9A0-4f46-9E9D-F661DC4874CD}").Replace("&nbsp;", "{5A255853-D9A0-4f46-9E9D-F661DC4874CD}");
      string format = "(?<==\\s*['\"][^'\"<>]*)(\\[{0}\\])(?=[^'\"<>]*[\"'])";

      foreach(DataColumn current in udt_dataset.Tables[DataSetTableName.Data].Columns)
      {
        input = Regex.Replace(input, string.Format(format, current.ColumnName), string.Format("{{udt:{0}}}", XmlConvert.EncodeName(current.ColumnName)));
        input = input.Replace(string.Format("[{0}]", current.ColumnName), string.Format("<xsl:value-of select=\"udt:{0}\"  disable-output-escaping=\"yes\"/>", XmlConvert.EncodeName(current.ColumnName)));  
      }

      foreach (string str4 in Enum.GetNames(typeof(ContextValues)))
        input = Regex.Replace(input, string.Format(format, "Context:" + str4), string.Format("{{/udt:UserDefinedTable/udt:Context/udt:{0}}}", str4)).Replace(string.Format("[Context:{0}]", str4), string.Format("<xsl:value-of select=\"/udt:UserDefinedTable/udt:Context/udt:{0}\"  disable-output-escaping=\"yes\"/>", str4));
      
      return PrettyPrint(input.Replace("[UDT:EditLink]", "<xsl:call-template name =\"EditLink\"/>").Replace("[UDT:DetailView]", "<xsl:call-template name =\"DetailView\"/>").Replace("[UDT:ListView]", "<xsl:call-template name =\"ListView\"/>")).Replace("{5A255853-D9A0-4f46-9E9D-F661DC4874CD}", "&#160;");
    }


  }

}

